import gtk
import server
import TCPServer
import TCPClient
import threading
import chat_list
import contact_list

from add_contact import WndAddContact
from chat        import WndChat
    

class LoginThread(threading.Thread):
    
    def __init__(self, win):
        self.win = win
        threading.Thread.__init__(self)
        
    def run(self):
        uname = self.win._builder.get_object("txt_username").get_text()
        pwd = self.win._builder.get_object("txt_password").get_text()
        
        if uname == '':
            gtk.gdk.threads_enter()
            dlg = gtk.MessageDialog(flags          = gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT,
                                    parent         = self.win._obj,
                                    type           = gtk.MESSAGE_WARNING,
                                    buttons        = gtk.BUTTONS_OK,
                                    message_format = "Please type a username.")
            dlg.run()
            dlg.destroy()
            gtk.gdk.threads_leave()
            return
            
        elif pwd == '':
            gtk.gdk.threads_enter()
            diag = gtk.MessageDialog(flags=gtk.DIALOG_MODAL,parent=self.win._obj, type=gtk.MESSAGE_WARNING,buttons=gtk.BUTTONS_OK,message_format="Please type a password.")
            diag.run()
            diag.destroy()
            gtk.gdk.threads_leave()
            return

        server.username = uname

        btn = self.win._builder.get_object("cmd_login")
        
            # Prevent from the user clicking multiple times on the Login
            #                              button during a login attempt
        btn.set_sensitive(False)

        res = TCPServer.start()
        if res != None:
            self.win.sb_login.push(0, res)
        
        else:
            img = self.win._builder.get_object("img_logo")
            img.set_from_file("pixbuf/logging.svg")
            
            self.win.sb_login.push(0,"Logging in...")
                    
            resp, err = server.login(uname, pwd)
            
            if (resp == "Success"):              # Login was successful!
                img.set_from_file("pixbuf/logged.svg")
                
                self.win._builder.get_object("mnu_login_disconnect").set_sensitive(True)
                self.win.sb_login.push(0, "Loading contact list...")
                
                                         # Load contact list from server
                contact_list.populate()

                self.win._builder.get_object("lbl_username").set_markup("<b>" + uname + "</b>")
                
                self.win.clthread = contact_list.ListThread()
                self.win.clthread.start()
                
                self.win.sb_login.push(0, "Connected.")
                
                self.win.nb.set_current_page(1)
                
            else:
                img.set_from_file("pixbuf/icon.svg")
                if err == None:
                    if res != None: msg = res
                    else: msg = "Wrong username/password."
                else: msg = err.strerror
                self.win.sb_login.push(0, msg)
                TCPServer.stop()
            
            img.set_from_file("pixbuf/icon.svg")
            
        btn.set_sensitive(True)

class LogoutThread(threading.Thread):
    def __init__(self, win):
        self.win = win
        threading.Thread.__init__(self)
        
    def run(self):
        self.win.sb_login.push(0,"Logging out...")
        
        server.logout(server.username)
        server.username = None
        self.win.nb.set_current_page(0)
        
        widget = self.win._builder.get_object("mnu_login_disconnect")
        widget.set_sensitive(False)
        chat_list.remove_all()
        
        try:
            self.win.clthread.stop()
        except AttributeError:
            pass
            
        contact_list.clear()
        TCPServer.stop()

        self.win.sb_login.push(0,"Disconnected.")
        self.win.img.set_from_file("pixbuf/icon.svg")

        
class WndMain:
    
    def __init__(self):
        self._builder = gtk.Builder()
        self._builder.add_from_file("main.glade")
        self._builder.connect_signals(self)
        
        self.sb_login = self._builder.get_object("sb_login")
        self.nb       = self._builder.get_object("nb_main")
        self.img      = self._builder.get_object("img_logo")
        self.ls_cl    = self._builder.get_object("ls_contact_list")
        self._obj     = self._builder.get_object("wnd_main")
        self._obj.show_all()
        
        contact_list._list = self.ls_cl
        
        chat_list.chat_list = list()
        
        server.username = None

########################################################################
##                                                                    ##
##  SIGNAL HANDLERS                                                   ##
##                                                                    ##
########################################################################
        
    def on_delete_event(self, obj, data = None):
        if server.username != None:
            self.on_mnu_login_disconnect_activate(self._builder.get_object("mnu_login_disconnect"))
        
        chat_list.remove_all()
        
        gtk.main_quit()
        
    def on_login(self, button, data = None):        
        LoginThread(self).start()

                    # TODO: Consider making this method a thread instead
    def on_mnu_login_disconnect_activate(self, widget, data = None):
        if server.username == None:
            return
            
        LogoutThread(self).start()

    def on_tb_main_add_contact_clicked(self, widget, data = None):
        addcontact = WndAddContact(self)

    def on_tv_contact_list_row_activated(self, treeview, path, view_column, user_param1=None):
        iter = self.ls_cl.get_iter(path)
        uname, ip, status, is_open = self.ls_cl.get(iter, 0, 1, 2, 4)
        
        if (status == 0) and (not is_open): return
        
                 # Determine whether a chat window with the same user is
                 #                                          already open
        win = chat_list.search(uname)
        if win != None: win._obj.present()
        else: WndChat(iter, uname, ip, True)
        
        self.ls_cl.set(iter, 4, True)
